"use client"
import { AspectRatio } from "@radix-ui/react-aspect-ratio"
import NextImage from "next/image" 
import {cn, fomatPrice} from "@/lib/utils"
import { Rnd } from "react-rnd"

import HandleComponent from "@/components/HandleComponent"
import { ScrollArea } from "@radix-ui/react-scroll-area"
import { RadioGroup } from '@headlessui/react'
import { useRef, useState } from "react"
import { COLORS, MODELS, MATERIALS, FINISHES } from "@/validators/option-validators"
import { Label } from "@radix-ui/react-label"
import { DropdownMenu, DropdownMenuContent, DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"
import { Button } from "@/components/ui/button"
import { ArrowRight, Check, ChevronsDown } from "lucide-react"
import { DropdownMenuItem } from "@/components/ui/dropdown-menu"
import { BASE_PRICE } from "@/config/products"

interface DesignConfiguratorProps {
  imageUrl: string,
  imageDimensions: { width: number, height: number }, // 图片宽高
}



// 价格 描述
const DesignConfigurator = ({ imageUrl, imageDimensions}: DesignConfiguratorProps) => {

  const [options, setOptions] = useState<{
    color:(typeof COLORS)[number]
    model:(typeof MODELS.options)[number]
    material:(typeof MATERIALS.options)[number]
    finish:(typeof FINISHES.options)[number]
  }>({
    color: COLORS[0],
    model: MODELS.options[0],
    material: MATERIALS.options[0],
    finish: FINISHES.options[0]
  })

// 被拉伸后的宽高
  const [renderDimensions, setRenderDimensions] = useState({
    width: imageDimensions.width / 4 ,
    height: imageDimensions.height / 4
  })

// 图片拖动后的定位 被拖动图片xy坐标 相对于整个区域
  const [renderedPosition, setRenderedPosition] = useState({
    x: 150,
    y: 205
  })

// 获取手机背景图 ref
const phoneCaseRef = useRef<HTMLDivElement>(null)
// 移动区域的 ref
const containerRef = useRef<HTMLDivElement>(null)

  async function saveConfiguration () {
    if (!phoneCaseRef.current) return 
    try {
      // 手机图片相对于 视口的 left top
      const { left: caseLeft, top: caseTop, width, height } = phoneCaseRef.current!.getBoundingClientRect()
      // 移动区域的 left top
      const { left: containerLeft, top: containerTop } = containerRef.current!.getBoundingClientRect()
      // 手机图片相对于移动区域的 left top
      const leftOffser = caseLeft - containerLeft
      const topOffser = caseTop - containerTop

      const acyualX = renderedPosition.x - leftOffser
      const acyualY = renderedPosition.y - topOffser

      // 将截取到的图片画在canvas中
      const canvas = document.createElement('canvas')
      canvas.width = width
      canvas.height = height
      const ctx = canvas.getContext('2d')

      const userImage = new Image()
      userImage.crossOrigin = 'anonymous'
      userImage.src = imageUrl
      await new Promise( (resolve ) => (userImage.onload = resolve))
      // 裁剪图片
      ctx?.drawImage(
        userImage,
        acyualX,
        acyualY,
        renderDimensions.width,
        renderDimensions.height,
      )

      // 截取图片的Base64
      const base64 = canvas.toDataURL()
      const base64Data = base64.split(',')[1]
      
      const blob = base64ToBlob(base64Data, 'image/png')
      const file = new File([blob], 'filename.png', { type: 'image/png' })
      

    } catch (err) {
      
    }
  }

  function base64ToBlob (base64: string, mimeType: string) {
    const byteCharacters = atob(base64) // 对 base64 解码
    const byteNumbers = new Array(byteCharacters.length)

    for (let i = 0; i < byteCharacters.length; i++) {
      byteNumbers[i] = byteCharacters.charCodeAt(i)
    }
    const byteArray = new Uint8Array(byteNumbers)
    return new Blob([byteArray], { type: mimeType })
  }

  return (
    <div className="relative mt-20 grid grid-col-1 lg:grid-cols-3 mb-20 pb-20">
      <div ref={containerRef} className="relative h-[37rem] overflow-hidden col-span-2 w-full max-w-4xl 
          flex item-center justify-center rounded-lg border-2 border-dashed border-gray-300 
          p-12 text-center focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-2
      ">
        <div className="relative w-60 bg-opacity-50 pointer-events-none aspect-[896/1831]">
          <AspectRatio ref={phoneCaseRef} ratio={896/1831} className="pointer-events-none relative z-50 aspect-[896/1831] w-full">
              <NextImage fill alt='phone image' src="/phone-template.png" className="pointer-events-none z-50 select-none"/>
          </AspectRatio>
          <div className="absolute z-40 inset-0 left-[3px] top-px right-[3px] bottom-px rounded-[32px] shadow-[0_0_0_99999px_rgba(229,231,235,0.6)]" />

          <div className={cn(
            'absolute inset-0 left-[3px] top-px right-[3px] bottom-px rounded-[32px]',
            `bg-${options.color.tw}`
          )} />
        </div>
        {/*  拖拽区域 */}
        <Rnd 
          default={{
            x: 150,
            y: 205,
            width: imageDimensions.width / 4,
            height: imageDimensions.height / 4
          }}
          onResizeStop={(_, __, ref, ___, { x, y }) => {
            console.log(ref, x, y, 'onResizeStop');
            
            setRenderDimensions({
              height: parseInt(ref.style.height.slice(0,-2)),
              width: parseInt(ref.style.width.slice(0,-2))
            })

            setRenderedPosition({x, y})
          }}
          onDragStop={(_, data) => {
            const { x, y } = data
            setRenderedPosition({x, y})
          }}

          className="absolute z-20 border-[3px] border-primary"
          lockAspectRatio
          resizeHandleComponent={{
            bottomRight: <HandleComponent />,
            bottomLeft: <HandleComponent />,
            topRight: <HandleComponent />,
            topLeft: <HandleComponent />
          }}
        >
          <div className="relative w-full h-full">
              <NextImage 
                src={imageUrl} 
                fill
                alt="img"
                className="pointer-event-none"
              />
          </div>
        </Rnd>
      </div>
      {/* 选择区域 */}
      <div className="h-[37.5rem] w-full col-span-full lg:col-span-1 flex flex-col  bg-white">
          <ScrollArea className="relative flex-1 overflow-auto">
              <div aria-hidden='true' className="absolute inset-x-0 bottom-0 h-12 bg-gradient-to-t from-white pointer-events-none" />

              <div className="px-8 pb-12 pt-8">
                <h2 className="tracking-tighter font-bold text-3xl ">
                  选择机型
                </h2>

                <div className="w-full h-px bg-zinc-200 my-6"></div>

                <div className="relative mt-4 h-full flex flex-col justify-between">
                  <div className="flex flex-col gap-6">
                  
                    <RadioGroup value={options.color} 
                      onChange={(val) => {
                        setOptions((prev) => ({
                          ...prev,
                          color: val
                        }))
                      }}
                    >
                      <Label> Colors: { options.color.label}</Label>
                      <div className="mt-3 flex items-center space-x-3">
                        {
                          COLORS.map((color) => (
                            <RadioGroup.Option 
                              key={color.label} 
                              value={color} 
                              className={
                                ({ active, checked }) => cn('relative -m-0.5 flex cursor-pointer items-center justify-center rounded-full p-0.5 active:ring-0 focus:ring:0 active:outline-none focus:outline-none border-2 border-transparent',
                                {
                                  [`border-${color.tw}`]: active || checked
                                }
                              )
                              }
                            >
                              <span className={cn(`bg-${color.tw}`, 'h-8 w-8 rounded-full border-black border-opacity-10')} />
                            </RadioGroup.Option>
                          ))
                        }
                      </div>
                    </RadioGroup>

                    <div className="relative flex flex-col gap-3 w-full">
                        <Label>型号: </Label>
                        <DropdownMenu>
                            <DropdownMenuTrigger asChild>
                              <Button variant='outline' role='combobox'
                                className="w-full justify-between"
                              >
                                {options.model.label}
                                <ChevronsDown className="ml-2 h-4 w-4 shrink-0 opacity-50 "></ChevronsDown>
                              </Button>
                            </DropdownMenuTrigger>
                            <DropdownMenuContent >
                                {
                                  MODELS.options.map((model) => (
                                    <DropdownMenuItem
                                      key={model.label}
                                      className={
                                        cn('flex text-sm gap-1 items-center p-1.5 cursor-default hover:bg-zinc-100',{
                                          'bg-zinc-100': options.model.label === model.label
                                        })
                                      }
                                      onClick={() => {
                                        setOptions((prev) => ({
                                          ...prev,
                                          model: model
                                        }))
                                      }}
                                    >
                                      <Check 
                                        className={cn('mr-2 h-4 w-4',
                                          model.label === options.model.label ? 'opacity-100' : 'opacity-0'
                                        )}
                                      />
                                      {model.label}
                                    </DropdownMenuItem>
                                  ))
                                }
                            </DropdownMenuContent>
                        </DropdownMenu>
                    </div>

                    {
                      [MATERIALS, FINISHES].map(({
                        name, options: selectableOptions
                      }) => (
                        <RadioGroup 
                          key={name}
                          value={options[name]}
                          onChange={(val) => {
                            setOptions((prev) => ({
                              ...prev,
                              [name]: val
                            }))
                          }}
                        >
                          <Label>
                            {
                              name.slice(0,1).toUpperCase() + name.slice(1)
                            }
                          </Label>
                          <div className="mt-3 space-y-4">
                            {
                              selectableOptions.map((option) => (
                                <RadioGroup.Option 
                                  key={option.value}
                                  value={option}
                                  className={({active, checked}) => 
                                    cn(
                                      `relative block cursor-pointer rounded-lg bg-white px-6 py-4 shadow-sm border-2 border-zinc-200 
                                        focus:outline-none ring-0 focus:ring-0 outline-none sm:flex sm:justify-between`,
                                        {
                                          'border-primary': active || checked,
                                        }
                                    )
                                  }
                                >
                                  <span className="flex items-center">
                                    <span className="flex flex-col text-sm">
                                      <RadioGroup.Label 
                                      className='font-medium text-gray-900'
                                      as="span">
                                        { option.label }
                                      </RadioGroup.Label>

                                      {
                                        option.description ? (
                                          <RadioGroup.Description
                                            as="span"
                                            className='text-gray-500'
                                          >
                                            <span className="block sm:inline">{ option.description}</span>
                                          </RadioGroup.Description>
                                        ) : null
                                      }
                                    </span>
                                  </span>

                                  <RadioGroup.Description 
                                    as='span'
                                    className='mt-2 flex text-sm sm:ml-4 sm:mt-0 sm:flex-col sm:text-right'
                                    >
                                      <span className="font-medium text-gray-900">
                                        { fomatPrice( option.price / 100) }
                                      </span>
                                  </RadioGroup.Description>
                                </RadioGroup.Option>
                              ))
                            }
                          </div>
                        </RadioGroup>
                      ))
                    }
                  </div>
                </div>

              </div>
          </ScrollArea>

          <div className="w-full px-8 h-16 bg-white">
            <div className="h-px w-full bg-zinc-200"></div>
            <div className="w-full h-full flex justify-end items-center">
              <p className="font-medium whitespace-nowrap">
                { fomatPrice((BASE_PRICE + options.finish.price + options.material.price) / 100) }
              </p>

              <Button 
                size='sm'
                className='w-full flex gap-6 ml-8'
                onClick={() => saveConfiguration()}
              >
                Continue
                <ArrowRight className="h-4 w-4 ml-1 inline"/>
              </Button>
            </div>
          </div>

      </div>

    </div>
  )
}

export default DesignConfigurator